package demo.db.dynamic;

import com.alibaba.fastjson.JSON;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import demo.db.dynamic.config.DsConfig;
import demo.db.dynamic.config.DynamicDsDemoConfig;
import demo.db.mybatis.dao.UserMapper;
import demo.db.mybatis.pojo.User;
import demo.db.mybatis.service.UserService;
import demo.java.sql.ConnectionDemo;
import demo.spring.framework.jdbc.datasource.lookup.RoutingDataSourceDemo;
import demo.vo.common.Page;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class DynamicDataSourceDemo {

    private static Logger logger = LoggerFactory.getLogger(DynamicDataSourceDemo.class);

    /**
     * 测试数据源切换
     */
    @Test
    public void test() {
        // @Configuration注解的spring容器加载方式，用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
        ApplicationContext context = new AnnotationConfigApplicationContext(DsConfig.class);
        ComboPooledDataSource masterDS = (ComboPooledDataSource) context.getBean("masterDS");
        try {
            Connection connection = masterDS.getConnection();
            ConnectionDemo.printTransactionIsolation(connection);
        } catch (SQLException e) {
            logger.error("", e);
        }
        // 如果加载spring-context.xml文件：
        // ApplicationContext context = new
        // ClassPathXmlApplicationContext("spring-context.xml");
    }

    /**
     * 测试数据源切换，通过注解标识主从库
     */
    @Test
    public void test2() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(DynamicDsDemoConfig.class);
        context.refresh();
        RoutingDataSourceDemo ds = context.getBean(RoutingDataSourceDemo.class);
        String realDsName = ds.getDatasource();
        System.err.println(realDsName);
        UserService userService = context.getBean(UserService.class);
        User user = userService.query(1);
        System.err.println("--------------");
        System.err.println(user);
        context.close();
    }

    /**
     * 读写分离。通过 sql 自动区分主从库
     */
    @Test
    public void test3() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(DynamicDsDemoConfig.class);
        context.refresh();
        UserMapper userMapper = context.getBean(UserMapper.class);
        int count = userMapper.countByMap(new HashMap<String, Object>());
        System.err.println("count = " + count);

        count = userMapper.insertUser("Nini" + new Random().nextInt(1000), (byte) 2);
        System.err.println("count = " + count);

        UserService userService = context.getBean(UserService.class);
        userService.add("Nana" + new Random().nextInt(1000));
        context.close();
    }

    /**
     * 分页查询
     */
    @Test
    public void testPage() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(DynamicDsDemoConfig.class);
        context.refresh();
        UserMapper userMapper = context.getBean(UserMapper.class);
        Map<String, Object> map = new HashMap<>();
        int total = userMapper.countByMap(map);
        List<User> list = Collections.emptyList();
        Integer pageNum = 1;
        Integer pageSize = 10;
        if (total > 0) {
            if (pageNum != null && pageSize != null) {
                map.put("offset", (pageNum - 1) * pageSize);
                map.put("rows", pageSize);
            }
            list = userMapper.selectByMap(map);
        }
        Page<User> page = new Page<>(pageNum, pageSize, total, list);
        System.out.println(JSON.toJSONString(page, true));
    }

}
